﻿using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using C9ShowNotesHelper.Utility;
using System.Windows.Media.Imaging;
using System.IO;
using System.Text;
using CredentialManager;

namespace C9ShowNotesHelper
{
   public partial class MainWindow : Window
  {
     bool ignoreValueChanged = false;
     string tempfolder = "";

     public MainWindow()
    {
      InitializeComponent();

    }

    private void playButton_Click(object sender, RoutedEventArgs e)
    {
      if (mediaElement1.Source == null)
      {
        bufferingIndicator.BusyContent = "Loading...";
        bufferingIndicator.IsBusy = true;
        
        timecodeListBox.Items.Clear();

        test.Source = new Uri(videoUrlTextBox.Text);

      }
      else
        if (mediaElement1.Source != new Uri(videoUrlTextBox.Text))
        {
          bufferingIndicator.BusyContent = "Loading...";
          bufferingIndicator.IsBusy = true; 
        
          mediaElement1.LoadedBehavior = System.Windows.Controls.MediaState.Manual;
          mediaElement1.Source = new Uri(videoUrlTextBox.Text);
        }
      
      mediaElement1.Play();
      
    }
      
    private void timecodeButton_Click(object sender, RoutedEventArgs e)
    {
      TimeSpan pos = mediaElement1.Position;

      var link = LinkHelper.GenerateLink(pos, showURLMRUComboBox.Text, episodeUrlTextBox.Text);
      timecodeTextBox.Text = link;
      
      //ClipboardHelper.CopyHtmlToClipBoard(link);

      timecode ti = new timecode();
      ti.timecodetext = string.Format("[T{0:00}:{1:00}]", pos.Minutes, pos.Seconds);

      ClipboardHelper.CopyHtmlToClipBoard(LinkHelper.GenerateLinkText(pos));

      ti.snapimage = mediaElement1.GetScreenShotAsRenderTargetBitmap(1,90);
      ti.linkurl = link;
      ti.position = pos;

      timecodeListBox.Items.Add(ti);
      timecodeListBox.SelectedIndex = timecodeListBox.Items.Count-1;
      timecodeListBox.ScrollIntoView(timecodeListBox.SelectedItem);
      
    }

    private void pauseButton_Click(object sender, RoutedEventArgs e)
    {
      if (test.Source == null)
        return;

      resumeButton.IsEnabled = true;
      pauseButton.IsEnabled = false;

      myBegin.Storyboard.Pause();

    }

    private void resumeButton_Click(object sender, RoutedEventArgs e)
    {
      resumeButton.IsEnabled = false;
      pauseButton.IsEnabled = true;

    }

    private void backButton_Click(object sender, RoutedEventArgs e)
    {
      if (test.Source == null)
        return;

      if ((positionSlider.Value - 10000) <= 0)
      {
        myBegin.Storyboard.Seek(mainGrid, TimeSpan.FromMilliseconds(0), TimeSeekOrigin.BeginTime);
      }
      else
      {
        myBegin.Storyboard.Seek(mainGrid, TimeSpan.FromMilliseconds(positionSlider.Value - 10000), TimeSeekOrigin.BeginTime);
      }

    }

    private void forwardButton_Click(object sender, RoutedEventArgs e)
    {
      if (test.Source == null)
        return;

      if ((positionSlider.Value + 10000) < positionSlider.Maximum)
        myBegin.Storyboard.Seek(mainGrid, TimeSpan.FromMilliseconds(positionSlider.Value + 10000), TimeSeekOrigin.BeginTime);

    }

    private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
      timecodeTextBox.Focus();
      C9ShowNotesHelper.Properties.Settings.Default.Save();
    }

    private void mediaElement1_MediaOpened(object sender, RoutedEventArgs e)
    {
      totalTimeLabel.Content = mediaElement1.NaturalDuration.TimeSpan.ToString("h\\:mm\\:ss");

      positionSlider.Maximum = mediaElement1.NaturalDuration.TimeSpan.TotalMilliseconds;
      
      bufferingIndicator.IsBusy = false;
      pauseButton.IsEnabled = true;
      forwardButton.IsEnabled = true;
      backButton.IsEnabled = true;
      timecodeButton.IsEnabled = true;
      resumeButton.IsEnabled = false;
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
      this.Title = this.Title + " (" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString() + ")";
      timecodeListBox.Items.Clear();
      tempfolder = Path.Combine(Path.GetTempPath(), "C9HelperTemp");
      Directory.CreateDirectory(tempfolder);

    }

    private void mediaElement1_MediaFailed(object sender, ExceptionRoutedEventArgs e)
    {
      bufferingIndicator.IsBusy = false;
      mediaElement1.Source = null;
      System.Windows.MessageBox.Show(e.OriginalSource.ToString() + " " + e.ErrorException.ToString(), "Error Loading Media");
    }

    private void mediaElement1_BufferingStarted(object sender, RoutedEventArgs e)
    {
      bufferingIndicator.BusyContent = "Buffering...";
      bufferingIndicator.IsBusy = true;
    }

    private void mediaElement1_BufferingEnded(object sender, RoutedEventArgs e)
    {
      bufferingIndicator.IsBusy = false;
    }
    
     private void MediaTimeChanged(object sender, EventArgs e)
    {
      ClockGroup clockGroup = sender as ClockGroup;
      MediaClock mediaClock = clockGroup.Children[0] as MediaClock;

      if (mediaClock.CurrentProgress.HasValue)
      {
        ignoreValueChanged = true;
        positionSlider.Value = mediaElement1.Position.TotalMilliseconds;
        positionLabel.Content = mediaElement1.Position.ToString("h\\:mm\\:ss");
        ignoreValueChanged = false;
      }

      
    }

     private void positionSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
     {
       if (ignoreValueChanged)
       {
         return;
       }

       myBegin.Storyboard.Seek(mainGrid, TimeSpan.FromMilliseconds(positionSlider.Value), TimeSeekOrigin.BeginTime);

       resumeButton.IsEnabled = false;
       pauseButton.IsEnabled = true;

     }

     private void showURLMRUComboBox_LostFocus(object sender, RoutedEventArgs e)
     {
       if (showURLMRUComboBox.Text.Length == 0)
         return;

       if (C9ShowNotesHelper.Properties.Settings.Default.showMRU.Contains(showURLMRUComboBox.Text) == false)
       {
         C9ShowNotesHelper.Properties.Settings.Default.showMRU.Add(showURLMRUComboBox.Text);
         showURLMRUComboBox.Items.Refresh();
       }
     }

     private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
     {
       switch (e.Uri.ToString())
       {
         case "clearmrulist":
           ClearMRUList();
           break;
         
         case "removeselected":
           RemoveSelectedItem();
           break;
         
         case "findshow":
           FindChannel9Show();
           break;

         case "findepisode":
           FindShowEpisode();
           break;
       }

    }

     private void timecodeListBox_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
     {
       if (timecodeListBox.SelectedItem == null)
         return;

       timecode ti = (timecode)timecodeListBox.SelectedItem;

       myBegin.Storyboard.Seek(mainGrid, ti.position, TimeSeekOrigin.BeginTime);

     }

     private void CopyTimeCodeHTML_Click(object sender, RoutedEventArgs e)
     {
       if (timecodeListBox.SelectedItem == null)
         return;

       timecode ti = (timecode)timecodeListBox.SelectedItem;

       var link = LinkHelper.GenerateLink(ti.position, showURLMRUComboBox.Text, episodeUrlTextBox.Text);
       
       ClipboardHelper.CopyHtmlToClipBoard(link);
     }

     private void CopyTimeCodeThumbnailHTML_Click(object sender, RoutedEventArgs e)
     {
       if (timecodeListBox.SelectedItem == null)
         return;

       timecode ti = (timecode)timecodeListBox.SelectedItem;

       PngBitmapEncoder png = new PngBitmapEncoder();
       png.Frames.Add(BitmapFrame.Create(ti.snapimage));

       string savefilename = Path.Combine(tempfolder, Path.GetRandomFileName() + ".png");

       using (Stream stm = File.Create(savefilename)) 
       {
        png.Save(stm);
       }

  
       var link = LinkHelper.GenerateLink(ti.position, showURLMRUComboBox.Text, episodeUrlTextBox.Text, savefilename, LinkHelper.LinkHTMLType.normal);
           
       ClipboardHelper.CopyHtmlToClipBoard(link);
     }

     private void CopyTimeCodeThumbnailHTMLTR_Click(object sender, RoutedEventArgs e)
     {
        //<tr>
        //<td valign="top"<a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-Apr-6-2012#time=2m25s"><img src="$tmpCB7E.tmp[3].png" width="244" height="139"></a></td>
        //<td valign="top"<a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-Apr-6-2012#time=2m25s">[2:25]</a> </td>
        //</tr>
       if (timecodeListBox.SelectedItem == null)
         return;

       timecode ti = (timecode)timecodeListBox.SelectedItem;

       PngBitmapEncoder png = new PngBitmapEncoder();
       png.Frames.Add(BitmapFrame.Create(ti.snapimage));

       string savefilename = Path.Combine(tempfolder, Path.GetRandomFileName() + ".png");

       using (Stream stm = File.Create(savefilename))
       {
         png.Save(stm);
       }

       var link = LinkHelper.GenerateLink(ti.position, showURLMRUComboBox.Text, episodeUrlTextBox.Text, savefilename, LinkHelper.LinkHTMLType.asTableRow);

       ClipboardHelper.CopyHtmlToClipBoard(link);

     }

     private void CopyAllAsTable_Click(object sender, RoutedEventArgs e)
     {
       if (timecodeListBox.Items.Count == 0)
         return;

       StringBuilder table = new StringBuilder();

       table.AppendLine("<table><tbody>");
       foreach (var v in timecodeListBox.Items)
       {
         timecode ti = (timecode)v;

         PngBitmapEncoder png = new PngBitmapEncoder();
         png.Frames.Add(BitmapFrame.Create(ti.snapimage));

         string savefilename = Path.Combine(tempfolder, Path.GetRandomFileName() + ".png");

         using (Stream stm = File.Create(savefilename))
         {
           png.Save(stm);
         }

         var link = LinkHelper.GenerateLink(ti.position, showURLMRUComboBox.Text, episodeUrlTextBox.Text, savefilename, LinkHelper.LinkHTMLType.asTableRow);
         table.AppendLine(link);
       }

       table.AppendLine("</tbody></table>");

       ClipboardHelper.CopyHtmlToClipBoard(table.ToString());
     
     }

     private void CopyAllAsDLDT_Click(object sender, RoutedEventArgs e)
     {
       if (timecodeListBox.Items.Count == 0)
         return;

       StringBuilder table = new StringBuilder();

       table.AppendLine("<dl class=twoCol>");
       foreach (var v in timecodeListBox.Items)
       {
         timecode ti = (timecode)v;

         PngBitmapEncoder png = new PngBitmapEncoder();
         png.Frames.Add(BitmapFrame.Create(ti.snapimage));

         string savefilename = Path.Combine(tempfolder, Path.GetRandomFileName() + ".png");

         using (Stream stm = File.Create(savefilename))
         {
           png.Save(stm);
         }

         var link = LinkHelper.GenerateLink(ti.position, showURLMRUComboBox.Text, episodeUrlTextBox.Text, savefilename, LinkHelper.LinkHTMLType.asC9DLDR);
         table.AppendLine(link);
       }

       table.AppendLine("</dl>");

       ClipboardHelper.CopyHtmlToClipBoard(table.ToString());

     }

     private void CopyAllTimecodeAsList_Click(object sender, RoutedEventArgs e)
     {
       if (timecodeListBox.Items.Count == 0)
         return;

       StringBuilder table = new StringBuilder();

       table.AppendLine("<ul>");
       foreach (var v in timecodeListBox.Items)
       {
         timecode ti = (timecode)v;

         var link = LinkHelper.GenerateLink(ti.position, showURLMRUComboBox.Text, episodeUrlTextBox.Text);
         table.AppendLine("<li>");
         table.AppendLine(link);
         table.AppendLine(" </li>");
       }

       table.AppendLine("</ul>");

       ClipboardHelper.CopyHtmlToClipBoard(table.ToString());

     }

     private void JumpToContentMenu_Click(object sender, RoutedEventArgs e)
     {
       if (timecodeListBox.SelectedItem == null)
         return;

       timecode ti = (timecode)timecodeListBox.SelectedItem;

       myBegin.Storyboard.Seek(mainGrid, ti.position, TimeSeekOrigin.BeginTime);
     }

     private void RemoveContentMenu_Click(object sender, RoutedEventArgs e)
     {
       if (timecodeListBox.SelectedItem == null)
         return;

       timecodeListBox.Items.Remove(timecodeListBox.SelectedItem);
     }

     private void ClearMRUList()
     {
       showURLMRUComboBox.Text = "";

       C9ShowNotesHelper.Properties.Settings.Default.showMRU.Clear();

       showURLMRUComboBox.Items.Refresh();
     }

     private void RemoveSelectedItem()
     {
       if (C9ShowNotesHelper.Properties.Settings.Default.showMRU.Contains(showURLMRUComboBox.Text))
       {
         C9ShowNotesHelper.Properties.Settings.Default.showMRU.Remove(showURLMRUComboBox.Text);

         showURLMRUComboBox.Text = "";
         showURLMRUComboBox.Items.Refresh();

         if (showURLMRUComboBox.Items.Count > 0)
         {
           showURLMRUComboBox.SelectedIndex = 0;
         }
       }
     }

     private void FindChannel9Show()
     {
       FindShow fs = new FindShow();
       fs.Owner = this;
       Nullable<bool> dialogResult = fs.ShowDialog();

       if (dialogResult == true)
       {
         Channel9WrapperLibrary.Show ss = fs.SelectedShow;
         if (ss != null)
         {
           C9ShowNotesHelper.Properties.Settings.Default.showMRU.Add(ss.Url);
           showURLMRUComboBox.Items.Refresh();
           showURLMRUComboBox.Text = ss.Url;
         }

       }
     }

     private void FindShowEpisode()
     {
       string C9UserID = "";
       string C9Key = "";
       string host = "Channel 9";
       bool savePwd = false;

       CREDUI_INFO info = new CREDUI_INFO();
       var _with1 = info;
       //_with1.hwndParent = this.Handle;
       _with1.pszCaptionText = host;
       _with1.pszMessageText = string.Format("Please Enter Credentials for {0}", host);

       CredUIReturnCodes result = default(CredUIReturnCodes);
       CREDUI_FLAGS flags = default(CREDUI_FLAGS);

       flags = CREDUI_FLAGS.GENERIC_CREDENTIALS
        | CREDUI_FLAGS.SHOW_SAVE_CHECK_BOX
        | CREDUI_FLAGS.EXPECT_CONFIRMATION;

       result = CredUI.PromptForCredentials(ref info, host, 0, ref C9UserID, ref C9Key, ref savePwd, flags);

       if (result == CredUIReturnCodes.NO_ERROR)
       {
         CredUI.ConfirmCredentials(host, true);
       }

       FindEpisode fe = new FindEpisode();
       fe.Owner = this;
       fe.ShowUrl = showURLMRUComboBox.Text;
       fe.C9UserID = C9UserID;
       fe.C9UserKey = C9Key;

       Nullable<bool> fedialogResult = fe.ShowDialog();

       if (fedialogResult == true)
       {
         Channel9WrapperLibrary.Episode se = fe.SelectedEpisode;
         if (se != null)
         {
           videoUrlTextBox.Text = se.WmvUrl;
           C9ShowNotesHelper.Properties.Settings.Default.LastUsedVideoURL = videoUrlTextBox.Text;
         }

       }

     }
     
  }

   public class timecode
   {
     public string timecodetext { get; set; }
     public RenderTargetBitmap snapimage { get; set; }
     public string linkurl { get; set; }
     public TimeSpan position { get; set; }

   }

}
